Programmation Client II¶

js Modules¶

C'est quoi le problème?¶

Les "vraies" affaires¶

  1. Les programmes consistent habituellement en plusieurs fichiers

  2. Les programmes utilisent habituellement des dépendances externes (react, mithril, angular, lodash)

  3. Votre programme sera probablement importer par d'autre programmes

Objectif: Les beauté de l'informatique¶

  1. Il est façile de copier quelque chose

  2. Il est façile de réutiliser quelque chose

Exemple¶

On veut calculer la moyenne d'un groupe d'étudiant. Nous travaillons dans un fichier students.js et nous avons un fichier stats.js avec des fonctions statistiques fait par une statisticienne.

Exemple | fichier stats.js¶

// stats.js
function average(lst){
    if(lst.length < 1){
        return NaN;
    }
    let sum = 0;
    let n = 0;
    for(const e of lst){
        sum += e;
        n += 1;
    }
    return sum / n;
}

Exemple | fichier students.js¶

// students.js

function getFinalGrades(students){
    const grades = [];
    for(const student of students){
        if(student.finalGrade){
            grades.push(finalGrade);
        }
    }
    return grades;
}

function studentAverage(students){
    const finalGrades = getFinalGrades(students);
    const ret = average(finalGrades);
    if(isNaN(ret)){
       return "Aucune note entrées";
    }
    return ret + "%"; 
}

Objectif | minimal¶

  1. Être capable de "merger" les deux fichiers dans le bon ordre

Objectif | hipster¶

  1. Être capable de "merger" les deux fichiers dans le bon ordre

    1. Juste prendre les fonctions que nous vonlons dans un ficher
    2. Être capable de ne pas "exporter" des fonctions
  2. Être capable d'importer des fonction de n'importe où

Terminologie¶

module¶

  1. C'est un fichier javascript

  2. Le fichier utilise une extension .js ou .jsm (javascript module)

  3. C'est une fichier qui peut importer d'autres modules

  4. C'est une fichier qui peut exporter des choses

  5. C'est un fichier qui est dans son propre "scope"/"namespace"

Importer¶

Si un module students.js utilise la fonction average du module stats.js on dira que le module students.js importe la fonction average du module stats.js.

Exporter¶

Si la fonction average du module stats.js peut être importer par un aute module, on dira que la fonction average est exporté par stats.js.

Notion de consentement¶

  1. Un module stats.js doit être consentant pour exporter une fonction average.

  2. Le module students.js n'a pas besoin de l'accord stats.js pour importer la fonction average

Utilisation d'un module dans un site web¶

Dans un fichier .js de la page web¶

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>title</title>
    <script type="module" src="script.js"></script>
</head>
<body>


</body>
</html>
  • La partie importante ici est vraiment le

Les events dans le html ne fonctionneront plus :(¶

Probleme¶

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>title</title>
    <script type="module" src="script.js"></script>
</head>
<body>

  <button onclick=sayHello() id="hello-button">Say Hello</button>
</body>
</html>
  • Meme si script.js contient la fonction sayHello(), cliquer le bouton ne fera rien :(

Solution¶

  • Ajouter l'event en javascript
function sayHello(){
    alert("Bonjour monde!");
}

document.getElementById("hello-button").addEventListener('click', sayHello);

Solution (html)¶

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <script type="module" src="script.js"></script>
</head>
<body>

  <button id="hello-button">Say Hello</button>
</body>
</html>

Avantage¶

  1. Un element peu avoir plusieurs "Event listener"
  2. On aime faire les choses en javascript

Exercices:¶

  • Faire une page web qui utilise un js module avec un boutton et qui aler "hello world" lorsqu'on clique sur le boutton

Importer des fonctions d'un module¶

Importer d'un module dans un fichier à côté¶

import {average} from "./stats.js";

Importer d'un module dans le plus loin¶

import {average} from "https://cdn.jsdelivr.net/gh/didiercrunch/cours-420-301-ah@main/modules-examples/stats.js";
In [15]:
import {average} from "https://cdn.jsdelivr.net/gh/didiercrunch/cours-420-301-ah@main/modules-examples/stats.js";

console.log(average([1,2,3,4]))
Out[15]:
2.5

La syntaxe¶

import {average} from "./stats.js";
  ^       ^       ^      ^ 
  1       2       3      4
  • 1 Le mot import est réservé
  • 2 définit ce que nous importons, c'est le nerf la guerre
  • 3 Le mot from est réservé
  • 4 L'url du module d'où on importe les chose

Importer une fonction¶

import {average} from "./stats.js";


console.log(average([10, 20, 30]));
  • Nous importons la fonction average
  • Dans ce fichier, nous aurons la fonction average définit dans ./stats.js

Importer deux fonctions¶

import {average, std} from "./stats.js";

console.log(average([10, 20, 30]));
console.log(std([10, 20, 30]));
  • Nous importons les fonctions average et std
  • Dans ce fichier, nous aurons les fonctions average et std définient dans ./stats.js

Renommer une fonction importé¶

import {std as standardDeviation} from "./stats.js";

console.log(standardDeviation([10, 20, 30]));
  • Nous importons la fonction std mais la renommons standardDeviation
  • Dans ce fichier, nous aurons toutes les fonctions définient dans ./stats.js

Importer toutes les fonctions¶

import * as stats from "./stats.js";

console.log(stats.average([10, 20, 30]));
  • Nous importons toutes les fonctions de /stats.js et les mettons dans un objet stats
  • Dans ce fichier, nous aurons toutes les fonctions définient dans ./stats.js

Exporter des fonctions d'un module¶

Dans un module, nous devons expliciter les variables (fonctions ou autre) que nous voulons exporter¶

export const INFINITY = 30;

export function average(lst){
    return 0;
}

export function std(lst){ 
    return 0;
}

La syntaxe¶

export const INFINITY = 30;
  ^       ^       ^      ^ 
  1       2       3      4
  • 1 Le mot export est réservé
  • 2 On devrait toujours exporter une constante
  • 3 Le nom de ce que nous exportons
  • 4 La valeur

La syntaxe (2)¶

export function average(lst){
    return 0;
}
  • export, on a compris, le mot "export" est magique

Export defaults¶

Problème¶

  • Il y a des modules qui veulent exporter une seule chose
    • connecteur à une base de donnée
    • mithril

Terminologie¶

  • "default" (adject)

Bibliographie¶

  • Une super BD https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/

  • La vraie doc: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules

  • V8 (aka google) https://v8.dev/features/modules